"""竹马法考爬虫"""
import re
import json
import time
from typing import List, Dict, Any, Optional
from datetime import datetime
from urllib.parse import urljoin, urlparse
import requests
from bs4 import BeautifulSoup
from app.core.database import RedisClient


class ZhumaScraper:
    """竹马法考爬虫"""
    
    BASE_URL = "https://www.zhumavip.com"
    API_BASE = f"{BASE_URL}/java-api"
    LOGIN_URL = f"{API_BASE}/api/user/login"  # 需要根据实际登录API调整
    SELECT_BY_CATALOG_URL = f"{API_BASE}/api/question/v2/selectByCatalogId"  # 首次获取题目（通过catalogId）
    QUESTION_LIST_URL = f"{API_BASE}/api/question/v2/getQuestionList"  # 获取题目列表（后续获取）
    QUESTION_DETAIL_URL = f"{API_BASE}/api/question/v2/getQuestionDetail"  # 获取题目详情（推测）
    
    def __init__(self):
        self.session = requests.Session()
        self.session.headers.update({
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36',
            'Accept': 'application/json, text/plain, */*',
            'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
            'Content-Type': 'application/json',
            'Origin': 'https://www.zhumavip.com',
            'Referer': 'https://www.zhumavip.com/',
            'appname': 'zhuma',
            'channel': 'zhumaWeb',
            'clienttype': 'web',
        })
        self.username = None
        self.logged_in = False
        self.token = None
        self.stoken = None
        self.mtoken = None
        
        # 尝试从Redis加载已保存的会话
        self._load_session()
    
    def _load_session(self):
        """从Redis加载已保存的会话"""
        try:
            redis = RedisClient.get_client()
            if redis:
                # 尝试加载最后一个登录用户的会话
                session_keys = redis.keys("zhuma:session:*")
                if session_keys:
                    # 使用最新的会话
                    latest_key = max(session_keys, key=lambda k: redis.ttl(k) if redis.ttl(k) > 0 else 0)
                    session_data = redis.get(latest_key)
                    if session_data:
                        session_info = json.loads(session_data)
                        self.username = session_info.get("username")
                        # 恢复cookies
                        cookies_dict = session_info.get("cookies", {})
                        for name, value in cookies_dict.items():
                            self.session.cookies.set(name, value)
                        # 恢复token
                        self.token = session_info.get("token")
                        self.stoken = session_info.get("stoken")
                        self.mtoken = session_info.get("mtoken")
                        if self.token:
                            self._update_headers()
                        self.logged_in = True
                        print(f"✅ 已加载 {self.username} 的登录会话")
        except Exception as e:
            print(f"加载会话失败: {e}")
    
    def _save_session(self):
        """保存会话到Redis"""
        if not self.username or not self.logged_in:
            return
        
        try:
            redis = RedisClient.get_client()
            if redis:
                session_key = f"zhuma:session:{self.username}"
                session_data = {
                    "username": self.username,
                    "cookies": dict(self.session.cookies),
                    "token": self.token,
                    "stoken": self.stoken,
                    "mtoken": self.mtoken,
                    "logged_in_at": datetime.now().isoformat()
                }
                # 保存7天
                redis.setex(session_key, 7 * 24 * 3600, json.dumps(session_data, ensure_ascii=False))
                print(f"✅ 已保存 {self.username} 的登录会话到Redis")
        except Exception as e:
            print(f"保存会话失败: {e}")
    
    def _update_headers(self):
        """更新请求头（包含token等）"""
        if self.token:
            self.session.headers.update({
                'token': self.token,
                'stoken': self.stoken or self.token,
                'mtoken': self.mtoken or self.token,
            })
    
    def login(self, username: str, password: str, token: Optional[str] = None, cookies: Optional[Dict[str, str]] = None) -> Dict[str, Any]:
        """
        登录竹马法考
        
        Args:
            username: 用户名
            password: 密码
            token: 如果已有token，可以直接使用（从浏览器cookies中获取）
            cookies: 如果已有cookies，可以直接使用
            
        Returns:
            登录结果
        """
        self.username = username
        
        # 如果提供了token和cookies，直接使用（从浏览器复制）
        if token and cookies:
            self.token = token
            self.stoken = token
            self.mtoken = token
            for name, value in cookies.items():
                self.session.cookies.set(name, value)
            self._update_headers()
            self.logged_in = True
            self._save_session()
            return {
                "success": True,
                "message": "使用提供的token登录成功",
                "username": username
            }
        
        try:
            # 注意：这里需要根据竹马法考的实际登录API调整
            # 可能需要先获取验证码、token等
            
            login_data = {
                "username": username,
                "password": password,
                # 可能还需要其他字段，如验证码、设备ID等
            }
            
            response = self.session.post(
                self.LOGIN_URL,
                json=login_data,
                timeout=10
            )
            
            if response.status_code == 200:
                result = response.json()
                
                # 根据实际API响应调整
                if result.get("code") == 200 or result.get("success"):
                    # 从响应或cookies中提取token
                    if "token" in result:
                        self.token = result["token"]
                    elif "stoken" in self.session.cookies:
                        self.token = self.session.cookies.get("stoken")
                    elif "token" in self.session.cookies:
                        self.token = self.session.cookies.get("token")
                    
                    self.stoken = self.session.cookies.get("stoken") or self.token
                    self.mtoken = self.session.cookies.get("mtoken") or self.token
                    
                    if self.token:
                        self._update_headers()
                    
                    self.logged_in = True
                    self._save_session()
                    return {
                        "success": True,
                        "message": "登录成功",
                        "username": username
                    }
                else:
                    error_msg = result.get("message", "登录失败")
                    return {
                        "success": False,
                        "message": error_msg
                    }
            else:
                return {
                    "success": False,
                    "message": f"登录请求失败: HTTP {response.status_code}"
                }
                
        except requests.RequestException as e:
            return {
                "success": False,
                "message": f"登录请求异常: {str(e)}"
            }
        except Exception as e:
            return {
                "success": False,
                "message": f"登录处理异常: {str(e)}"
            }
    
    def check_login_status(self) -> Dict[str, Any]:
        """检查登录状态"""
        if not self.logged_in:
            return {
                "logged_in": False,
                "message": "未登录"
            }
        
        # 尝试访问需要登录的页面验证
        try:
            # 这里可以访问一个需要登录的API来验证
            response = self.session.get(f"{self.BASE_URL}/api/user/info", timeout=5)
            if response.status_code == 200:
                return {
                    "logged_in": True,
                    "username": self.username,
                    "message": "登录状态有效"
                }
            else:
                self.logged_in = False
                return {
                    "logged_in": False,
                    "message": "登录状态已失效，请重新登录"
                }
        except Exception as e:
            return {
                "logged_in": self.logged_in,
                "username": self.username,
                "message": f"无法验证登录状态: {str(e)}"
            }
    
    def get_exam_years(self) -> List[int]:
        """获取可用的考试年份列表"""
        if not self.logged_in:
            return []
        
        try:
            # 这里需要根据实际API调整
            response = self.session.get(self.EXAM_LIST_URL, timeout=10)
            if response.status_code == 200:
                data = response.json()
                # 解析年份列表（需要根据实际响应格式调整）
                years = []
                # 示例：假设返回格式为 {"years": [2024, 2023, 2022, ...]}
                if isinstance(data, dict) and "years" in data:
                    years = data["years"]
                elif isinstance(data, list):
                    # 如果直接返回年份列表
                    years = data
                
                return sorted(years, reverse=True)
        except Exception as e:
            print(f"获取年份列表失败: {e}")
        
        # 默认返回最近5年
        current_year = datetime.now().year
        return list(range(current_year - 4, current_year + 1))
    
    def select_by_catalog_id(
        self,
        answer_id: str,
        catalog_id: int,
        question_type_id: int = 705,
        business_type_id: int = 104,
        kind_id: int = 2,
        code: int = 2,
        again_or_continue: int = 0
    ) -> Dict[str, Any]:
        """
        通过catalogId首次获取题目（获取初始题目和questionIds）
        
        Args:
            answer_id: 答案ID
            catalog_id: 目录ID（从URL中获取，如9305）
            question_type_id: 题目类型ID（默认705）
            business_type_id: 业务类型ID（默认104）
            kind_id: 类型ID（默认2）
            code: 代码（默认2）
            again_or_continue: 再次或继续（0=继续，1=重新开始）
            
        Returns:
            包含题目列表和questionIds的字典
        """
        if not self.logged_in:
            print("❌ 未登录，无法获取题目")
            return {}
        
        try:
            import time
            import uuid
            
            # 生成动态请求头
            nonce = str(uuid.uuid4())
            ts = str(int(time.time() * 1000))
            accept_q = 'e62c76572b7e5dd8e26d49ddc47f6132'  # 从你的请求中获取
            
            headers = {
                'accept-q': accept_q,
                'nonce': nonce,
                'ts': ts,
            }
            self.session.headers.update(headers)
            
            payload = {
                "answerId": answer_id,
                "code": code,
                "kindId": kind_id,
                "businessTypeId": business_type_id,
                "catalogId": catalog_id,
                "questionTypeId": question_type_id,
                "againOrContinue": again_or_continue
            }
            
            response = self.session.post(
                self.SELECT_BY_CATALOG_URL,
                json=payload,
                timeout=30
            )
            
            if response.status_code == 200:
                data = response.json()
                print(f"✅ selectByCatalogId 成功，响应键: {list(data.keys()) if isinstance(data, dict) else 'list'}")
                return data
            else:
                print(f"❌ selectByCatalogId 失败: HTTP {response.status_code}")
                print(f"响应内容: {response.text[:500]}")
                return {}
                
        except Exception as e:
            print(f"❌ selectByCatalogId 异常: {e}")
            import traceback
            traceback.print_exc()
            return {}
    
    def get_question_list(self, answer_id: str, is_begin: int = 1, question_ids: Optional[List[int]] = None, batch_size: int = 50) -> List[Dict[str, Any]]:
        """
        获取题目列表（根据answerId）
        
        Args:
            answer_id: 答案ID（从真题页面获取）
            is_begin: 是否开始（1=是，0=否）
            question_ids: 题目ID列表（可选，用于获取特定题目）
            
        Returns:
            题目列表
        """
        if not self.logged_in:
            print("❌ 未登录，无法获取题目列表")
            return []
        
        try:
            import time
            import uuid
            import hashlib
            
            # 生成动态请求头
            nonce = str(uuid.uuid4())
            ts = str(int(time.time() * 1000))
            
            # accept-q 可能是某种签名，暂时使用固定值（如果失败，可能需要分析生成逻辑）
            # 可以尝试从之前的请求中获取，或者分析其生成算法
            accept_q = '13a0a7c54b9f6f6bda317a8baf15dc00'  # 从你的请求中获取，可能需要动态生成
            
            headers = {
                'accept-q': accept_q,
                'nonce': nonce,
                'ts': ts,
            }
            self.session.headers.update(headers)
            
            payload = {
                "answerId": answer_id,
                "isBegin": is_begin
            }
            
            # 如果提供了question_ids，添加到请求体中（可以传入多个，一次性获取更多题目）
            if question_ids:
                # 限制每次请求的questionIds数量，避免请求过大
                payload["questionIds"] = question_ids[:batch_size] if len(question_ids) > batch_size else question_ids
            
            response = self.session.post(
                self.QUESTION_LIST_URL,
                json=payload,
                timeout=30
            )
            
            if response.status_code == 200:
                data = response.json()
                print(f"✅ 获取题目列表成功，响应键: {list(data.keys()) if isinstance(data, dict) else 'list'}")
                
                # 解析响应（根据实际响应格式：data.questions）
                if isinstance(data, dict):
                    if "data" in data:
                        data_obj = data["data"]
                        if isinstance(data_obj, dict):
                            # 优先查找 questions 字段
                            question_list = data_obj.get("questions", [])
                            if not question_list:
                                question_list = data_obj.get("list", [])
                        elif isinstance(data_obj, list):
                            question_list = data_obj
                        else:
                            question_list = []
                    elif "questions" in data:
                        question_list = data["questions"]
                    elif "list" in data:
                        question_list = data["list"]
                    elif "result" in data:
                        question_list = data["result"]
                        if isinstance(question_list, dict) and "list" in question_list:
                            question_list = question_list["list"]
                    else:
                        # 如果找不到，尝试返回整个data（可能是题目数组）
                        question_list = []
                        # 检查data中是否有题目相关的字段
                        for key in data.keys():
                            if isinstance(data[key], list) and len(data[key]) > 0:
                                # 检查第一个元素是否像题目对象
                                first_item = data[key][0]
                                if isinstance(first_item, dict) and ("content" in first_item or "question" in first_item or "title" in first_item or "questionName" in first_item):
                                    question_list = data[key]
                                    break
                elif isinstance(data, list):
                    question_list = data
                else:
                    question_list = []
                
                if question_list:
                    print(f"📊 解析到 {len(question_list)} 道题目")
                else:
                    print(f"⚠️ 未解析到题目，响应结构: {list(data.keys()) if isinstance(data, dict) else 'list'}")
                return question_list if question_list else []
            else:
                print(f"❌ 获取题目列表失败: HTTP {response.status_code}")
                print(f"响应内容: {response.text[:500]}")
                return []
                
        except Exception as e:
            print(f"❌ 获取题目列表异常: {e}")
            import traceback
            traceback.print_exc()
            return []
    
    def scrape_by_catalog(
        self,
        answer_id: str,
        catalog_id: int,
        year: int,
        question_type_id: int = 705,
        business_type_id: int = 104,
        kind_id: int = 2,
        max_questions: int = 200,
        batch_size: int = 50  # 每次请求的questionIds数量
    ) -> List[Dict[str, Any]]:
        """
        通过catalogId爬取题目（推荐方式）
        
        Args:
            answer_id: 答案ID
            catalog_id: 目录ID（从URL中获取，如9305）
            year: 年份
            question_type_id: 题目类型ID
            business_type_id: 业务类型ID
            kind_id: 类型ID
            max_questions: 最多爬取的题目数
            batch_size: 每次请求的questionIds数量（可以设置更大，如50-100）
            
        Returns:
            题目列表
        """
        if not self.logged_in:
            print("❌ 未登录，无法爬取题目")
            return []
        
        questions = []
        all_question_ids = set()
        
        try:
            print(f"📥 开始爬取 answerId: {answer_id}, catalogId: {catalog_id}")
            
            # 第一步：通过selectByCatalogId获取初始题目
            initial_data = self.select_by_catalog_id(
                answer_id=answer_id,
                catalog_id=catalog_id,
                question_type_id=question_type_id,
                business_type_id=business_type_id,
                kind_id=kind_id
            )
            
            if not initial_data:
                print("❌ 初始获取失败")
                return []
            
            # 解析初始响应，获取题目列表和questionIds
            initial_questions = []
            initial_question_ids = []
            
            # 尝试从响应中提取题目和questionIds
            if isinstance(initial_data, dict):
                # 查找题目列表
                if "data" in initial_data:
                    data = initial_data["data"]
                    if isinstance(data, dict):
                        initial_questions = data.get("list", []) or data.get("questions", [])
                        # 注意：API返回的是 questionsIds（复数），是对象数组，需要提取id字段
                        questions_ids_objects = data.get("questionsIds", []) or data.get("questionIds", [])
                        # 提取ID列表（questionsIds可能是对象数组，每个对象有id字段）
                        if questions_ids_objects:
                            if isinstance(questions_ids_objects[0], dict):
                                initial_question_ids = [item.get("id") for item in questions_ids_objects if item.get("id")]
                            else:
                                initial_question_ids = questions_ids_objects
                    elif isinstance(data, list):
                        initial_questions = data
                elif "list" in initial_data:
                    initial_questions = initial_data["list"]
                elif "questions" in initial_data:
                    initial_questions = initial_data["questions"]
                
                # 查找questionIds（支持两种格式）
                if "questionsIds" in initial_data:
                    questions_ids_objects = initial_data["questionsIds"]
                    if questions_ids_objects and isinstance(questions_ids_objects[0], dict):
                        initial_question_ids = [item.get("id") for item in questions_ids_objects if item.get("id")]
                    else:
                        initial_question_ids = questions_ids_objects
                elif "questionIds" in initial_data:
                    initial_question_ids = initial_data["questionIds"]
                elif "data" in initial_data and isinstance(initial_data["data"], dict):
                    questions_ids_objects = initial_data["data"].get("questionsIds", []) or initial_data["data"].get("questionIds", [])
                    if questions_ids_objects:
                        if isinstance(questions_ids_objects[0], dict):
                            initial_question_ids = [item.get("id") for item in questions_ids_objects if item.get("id")]
                        else:
                            initial_question_ids = questions_ids_objects
            
            # 解析初始题目
            for item in initial_questions:
                question = self._parse_question_item(item, year)
                if question:
                    questions.append(question)
                    original_id = item.get("id") or item.get("questionId")
                    if original_id:
                        all_question_ids.add(original_id)
            
            print(f"✅ 初始获取 {len(initial_questions)} 道题目，questionIds: {len(initial_question_ids)} 个")
            
            # 如果没有获取到questionIds，尝试从题目中提取
            if not initial_question_ids:
                initial_question_ids = [item.get("id") or item.get("questionId") for item in initial_questions if item.get("id") or item.get("questionId")]
            
            if not initial_question_ids:
                print("⚠️ 未获取到questionIds，无法继续分页")
                return questions
            
            # 第二步：通过getQuestionList批量获取更多题目
            # 从questionIds中偏移10个后，批量获取
            offset = 10
            page = 1
            
            while len(questions) < max_questions and offset < len(initial_question_ids):
                page += 1
                print(f"  📄 获取第 {page} 批（从偏移 {offset} 开始，批量 {batch_size} 个）...")
                
                # 获取下一批questionIds（偏移10个后，取batch_size个）
                batch_question_ids = initial_question_ids[offset:offset + batch_size]
                
                if not batch_question_ids:
                    print(f"  ✅ 已获取所有题目（共 {len(questions)} 道）")
                    break
                
                # 通过getQuestionList获取这批题目
                question_list = self.get_question_list(
                    answer_id=answer_id,
                    is_begin=0,
                    question_ids=batch_question_ids,
                    batch_size=batch_size
                )
                
                if not question_list:
                    print(f"  ⚠️ 第 {page} 批未获取到题目，尝试下一批")
                    offset += batch_size
                    time.sleep(1)
                    continue
                
                # 解析新获取的题目
                new_count = 0
                for item in question_list:
                    original_id = item.get("id") or item.get("questionId")
                    # 检查是否已存在
                    if original_id and original_id in all_question_ids:
                        continue
                    
                    question = self._parse_question_item(item, year)
                    if question:
                        questions.append(question)
                        new_count += 1
                        if original_id:
                            all_question_ids.add(original_id)
                
                print(f"  ✅ 第 {page} 批获取 {new_count} 道新题目，累计 {len(questions)} 道")
                
                # 更新偏移量（偏移10个，然后取下一批）
                offset += 10
                
                # 如果已经获取了所有questionIds，停止
                if offset >= len(initial_question_ids):
                    print(f"  ✅ 已遍历所有questionIds")
                    break
                
                # 添加延迟，避免请求过快
                time.sleep(1.5)
            
            print(f"✅ answerId {answer_id}: 共爬取 {len(questions)} 道题目")
            return questions
            
        except Exception as e:
            print(f"❌ 爬取失败: {e}")
            import traceback
            traceback.print_exc()
            return questions
    
    def scrape_year(self, year: int, answer_ids: Optional[List[str]] = None, catalog_info: Optional[List[Dict[str, Any]]] = None, max_questions_per_answer: int = 200) -> List[Dict[str, Any]]:
        """
        爬取指定年份的真题
        
        Args:
            year: 年份
            answer_ids: 答案ID列表（如果知道的话，可以从真题页面获取）
            catalog_info: 目录信息列表，格式：[{"answer_id": "...", "catalog_id": 9305, "question_type_id": 705, ...}]
            max_questions_per_answer: 每个answerId最多爬取的题目数
            
        Returns:
            题目列表
        """
        if not self.logged_in:
            print("❌ 未登录，无法爬取题目")
            return []
        
        questions = []
        
        try:
            # 优先使用catalog_info（更准确）
            if catalog_info:
                for info in catalog_info:
                    answer_id = info.get("answer_id")
                    catalog_id = info.get("catalog_id")
                    if not answer_id or not catalog_id:
                        continue
                    
                    result = self.scrape_by_catalog(
                        answer_id=answer_id,
                        catalog_id=catalog_id,
                        year=year,
                        question_type_id=info.get("question_type_id", 705),
                        business_type_id=info.get("business_type_id", 104),
                        kind_id=info.get("kind_id", 2),
                        max_questions=max_questions_per_answer,
                        batch_size=info.get("batch_size", 50)  # 可以设置更大的批量
                    )
                    questions.extend(result)
                    time.sleep(2)
            
            # 如果没有catalog_info，使用answer_ids（需要先调用selectByCatalogId）
            elif answer_ids:
                print("⚠️ 仅提供answer_ids，需要catalog_id信息，请使用catalog_info参数")
                print("提示：从URL中提取catalogId参数，格式：{\"answer_id\": \"...\", \"catalog_id\": 9305, ...}")
                return []
            else:
                print(f"⚠️ 未提供answer_ids或catalog_info")
                return []
            
            print(f"✅ {year}年: 成功爬取 {len(questions)} 道题目")
            
        except Exception as e:
            print(f"❌ 爬取 {year} 年题目失败: {e}")
            import traceback
            traceback.print_exc()
        
        return questions
    
    def _parse_question_type(self, item: Dict[str, Any]) -> str:
        """
        根据API返回的数据判断题目类型
        
        Args:
            item: 题目数据项
            
        Returns:
            题目类型: single_choice, multiple_choice, indefinite_choice
        """
        # 优先使用tagName判断（最直观准确）
        tag_name = item.get("tagName", "").strip()
        if tag_name:
            tag_name_lower = tag_name.lower()
            if "单选" in tag_name or "danxuan" in tag_name_lower:
                return "single_choice"  # 单选
            elif "多选" in tag_name or "duoxuan" in tag_name_lower:
                return "multiple_choice"  # 多选
            elif "不定项" in tag_name or "budingxiang" in tag_name_lower or "bdx" in tag_name_lower:
                return "indefinite_choice"  # 不定项选择
        
        # 其次使用tagId判断
        tag_id = item.get("tagId", "").lower()
        if tag_id:
            if "danxuan" in tag_id or tag_id == "01":
                return "single_choice"  # 单选
            elif "duoxuan" in tag_id or tag_id == "02":
                return "multiple_choice"  # 多选
            elif "budingxiang" in tag_id or "bdx" in tag_id or tag_id == "03":
                return "indefinite_choice"  # 不定项选择
        
        # 使用kind字段判断
        kind = item.get("kind", "")
        if kind == "01":
            return "single_choice"  # 单选
        elif kind == "02":
            return "multiple_choice"  # 多选
        elif kind == "03":
            return "indefinite_choice"  # 不定项选择
        
        # 根据题目内容判断（如果包含"正确的有"、"错误的是"、"哪些"等，可能是多选或不定项）
        content = item.get("content") or item.get("question") or item.get("questionName") or ""
        if ("正确的有" in content or "错误的是" in content or "正确的包括" in content or 
            "哪些" in content or "哪几" in content or "哪项" in content and "哪项" not in content[:50]):
            # 需要进一步判断是多选还是不定项
            # 通常不定项选择的答案可能只有一个，多选通常有多个
            # 这里先标记为不定项，后续可以根据答案数量调整
            return "indefinite_choice"
        
        # 默认返回单选
        return "single_choice"
    
    def _parse_question_item(self, item: Dict[str, Any], year: int) -> Optional[Dict[str, Any]]:
        """解析题目数据项"""
        try:
            # 根据实际API响应格式解析
            question_id = item.get("id") or item.get("questionId") or item.get("question_id")
            content = item.get("content") or item.get("title") or item.get("question") or item.get("questionName", "")
            options = item.get("options") or item.get("optionList") or []
            correct_answer = item.get("correctAnswer") or item.get("answer") or item.get("correct_answer") or item.get("answerArr", "")
            explanation = item.get("explanation") or item.get("analysis") or item.get("parse")
            subject = item.get("subject") or item.get("subjectName") or ""
            category = item.get("category") or item.get("categoryName") or ""
            
            if not question_id or not content:
                return None
            
            # 判断题目类型
            question_type = self._parse_question_type(item)
            
            # 格式化选项
            formatted_options = []
            if isinstance(options, list):
                for i, opt in enumerate(options):
                    if isinstance(opt, dict):
                        opt_text = opt.get("content") or opt.get("text") or opt.get("option")
                        formatted_options.append(f"选项{chr(65+i)}：{opt_text}")
                    else:
                        formatted_options.append(f"选项{chr(65+i)}：{opt}")
            elif isinstance(options, str):
                # 如果选项是字符串，尝试解析
                formatted_options = [f"选项{chr(65+i)}：{opt}" for i, opt in enumerate(options.split("\n")) if opt.strip()]
            
            # 处理答案（如果是数组，转换为字符串）
            if isinstance(correct_answer, list):
                if question_type == "multiple_choice" or question_type == "indefinite_choice":
                    # 多选或不定项，答案可能是多个
                    correct_answer = "、".join([str(a) for a in correct_answer])
                else:
                    # 单选，取第一个
                    correct_answer = str(correct_answer[0]) if correct_answer else "选项A"
            elif not correct_answer:
                correct_answer = "选项A"
            
            return {
                "question_id": f"zhuma_{year}_{question_id}",
                "content": content,
                "options": formatted_options if formatted_options else [
                    "选项A：待补充",
                    "选项B：待补充",
                    "选项C：待补充",
                    "选项D：待补充"
                ],
                "correct_answer": correct_answer,
                "explanation": explanation or "解析待补充",
                "type": question_type,  # 使用解析出的题目类型
                "difficulty": self._parse_difficulty(item.get("difficulty", "medium")),
                "category": category,
                "subject": self._map_subject(subject),
                "year": year,
                "exam_type": item.get("examType", "客观题"),
                "source": "scraped",
                "knowledge_points": item.get("knowledgePoints", []) if isinstance(item.get("knowledgePoints"), list) else [],
                "difficulty_score": None,
                "wrong_count": 0,
                "correct_count": 0,
                # 保存原始类型信息，便于后续查询
                "original_kind": item.get("kind", ""),
                "original_tagId": item.get("tagId", ""),
                "original_tagName": item.get("tagName", "")  # 保存tagName，包含"单选"、"多选"、"不定项"等
            }
        except Exception as e:
            print(f"解析题目失败: {e}")
            import traceback
            traceback.print_exc()
            return None
    
    def get_question_detail(self, question_id: str) -> Optional[Dict[str, Any]]:
        """获取题目详情（如果需要单独获取详情）"""
        if not self.logged_in:
            return None
        
        try:
            import time
            import uuid
            
            headers = {
                'accept-q': '02f3e7af2f5e1147dcb849cf34185e7f',
                'nonce': str(uuid.uuid4()),
                'ts': str(int(time.time() * 1000)),
            }
            self.session.headers.update(headers)
            
            payload = {
                "questionId": question_id
            }
            
            response = self.session.post(
                self.QUESTION_DETAIL_URL,
                json=payload,
                timeout=10
            )
            
            if response.status_code == 200:
                data = response.json()
                # 解析题目详情
                return self._parse_question_item(data, None)
        except Exception as e:
            print(f"获取题目详情失败: {e}")
        
        return None
    
    def _parse_difficulty(self, difficulty: str) -> str:
        """解析难度"""
        difficulty_map = {
            "1": "easy",
            "2": "medium",
            "3": "hard",
            "简单": "easy",
            "中等": "medium",
            "困难": "hard"
        }
        return difficulty_map.get(difficulty, "medium")
    
    def _map_subject(self, subject: str) -> str:
        """将中文科目名映射到英文标识"""
        subject_map = {
            "民法": "civil_law",
            "民诉": "civil_procedure",
            "民事诉讼法": "civil_procedure",
            "刑法": "criminal_law",
            "刑诉": "criminal_procedure",
            "刑事诉讼法": "criminal_procedure",
            "行政": "administrative",
            "行政法": "administrative",
            "商经": "commercial",
            "商法": "commercial",
            "经济法": "commercial",
            "三国": "international",
            "国际法": "international",
            "综合": "comprehensive"
        }
        return subject_map.get(subject, "comprehensive")


# 单例实例
zhuma_scraper = ZhumaScraper()

